package com.lanlion.portlet.http;

import com.lanlion.portlet.tool.MyX509TrustManager;
import com.lanlion.portlet.tool.StreamUtils;
import org.apache.commons.codec.binary.Hex;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;

/**
 * Author: zhangyu1@qiku.com
 * Title: Http请求连接池
 * Remark:支持HTTP，Https请求
 * Time:2017/1/3
 */
public class HttpConnectionManager {

    HttpClientContext context = null;
    PoolingHttpClientConnectionManager cm = null;

    public HttpConnectionManager() {
        this.init(null,null);
    }

    /**
     * http请求初始化
     * @param keyPath .p12文件路径
     * @param key 秘钥
     */
    HttpConnectionManager(String keyPath,String key) {
        this.init(keyPath,key);
    }



    public void init(String cert,String key) {
        SSLConnectionSocketFactory sslsf = null;
        try {
            if(null==cert || null == key){
                sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
            }else if(null!=cert && null != key){
                FileInputStream file = new FileInputStream(cert);
                String s1 = Hex.encodeHexString(StreamUtils.copyToByteArray(file));
                // 解密出16进制原证书文件内容为字节数组
                byte[] bytes = Hex.decodeHex(s1.toCharArray());
                ByteArrayInputStream input = new ByteArrayInputStream(bytes);
                KeyStore clientTrustKeyStore = KeyStore.getInstance("PKCS12");
                clientTrustKeyStore.load(input, key.toCharArray());
                KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                kmf.init(clientTrustKeyStore, key.toCharArray());
                TrustManager[] tm = {new MyX509TrustManager()};
                SSLContext sslContext = SSLContext.getInstance("TLSv1");
                sslContext.init(kmf.getKeyManagers(), tm, new java.security.SecureRandom());
                sslsf = new SSLConnectionSocketFactory(sslContext);
            }




        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(80);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public CloseableHttpClient getHttpClient() {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm).build();
        context = HttpClientContext.create();
        return httpClient;
    }


    public HttpClientContext getContext() {
        return context;
    }

    public void setContext(HttpClientContext context) {
        this.context = context;
    }
}
